import * as THREE from "three";
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 导入动画库
import gsap from "gsap";
// 导入dat.gui
import * as dat from "dat.gui";
// 灯光阴影
// 1、材质要满足能够对光照有反应
// 2、设置渲染器开启阴影的计算 renderer.shadowMap.enabled = true;
// 3、设置光照投射阴影 directionalLight.castShadow = true;
// 4、设置物体投射阴影 cube.castShadow = true;
// 5、设置物体接收阴影 plane.receiveShadow = true;

const scene = new THREE.Scene();
const gui = new dat.GUI();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);

// 设置相机位置
camera.position.set(0, 0, 10);
scene.add(camera);

// 添加物体
// 创建几何体
const cubeGeometry = new THREE.SphereBufferGeometry(1, 20, 20);
const cubeMaterial = new THREE.MeshStandardMaterial();
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
// 投射阴影
cube.castShadow = true;
// 将几何体添加到场景中
scene.add(cube);
// 创建平面
const planeGeometry = new THREE.PlaneBufferGeometry(50, 50);
const plane = new THREE.Mesh(planeGeometry, cubeMaterial);
plane.position.set(0, -1, 0);
plane.rotation.x = -Math.PI / 2;
// 接收阴影
plane.receiveShadow = true;
scene.add(plane);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 渲染器开启阴影的计算
renderer.shadowMap.enabled = true;
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼，让控制器更有真实效果,必须在动画循环里调用.update()。
controls.enableDamping = true;

// 添加坐标轴辅助器
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

// 灯光
// 环境光
const light = new THREE.AmbientLight(0xffffff, 0.5); // soft white light
scene.add(light);
//直线光源
// const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
// directionalLight.position.set(10, 10, 10);
// // 设置光照投射阴影
// directionalLight.castShadow = true;
// // 设置阴影贴图模糊度
// directionalLight.shadow.radius = 20;
// // 设置阴影贴图的分辨率
// directionalLight.shadow.mapSize.set(4096, 4096);
// // 设置平行光投射相机的属性
// directionalLight.shadow.camera.near = 0.5;
// directionalLight.shadow.camera.far = 500;
// directionalLight.shadow.camera.top = 5;
// directionalLight.shadow.camera.bottom = -5;
// directionalLight.shadow.camera.left = -5;
// directionalLight.shadow.camera.right = 5;
// scene.add(directionalLight);
// gui
//   .add(directionalLight.shadow.camera, "near")
//   .min(0)
//   .max(10)
//   .step(0.1)
//   .onChange(() => {
//     directionalLight.shadow.camera.updateProjectionMatrix();
//   });
// gui
//   .add(directionalLight.shadow.camera, "far")
//   .min(100)
//   .max(1000)
//   .step(1)
//   .onChange(() => {
//     directionalLight.shadow.camera.updateProjectionMatrix();
//   });

// 聚光灯
const spotLight = new THREE.SpotLight(0xffffff, 1);
spotLight.position.set(5, 5, 5);
spotLight.castShadow = true;
spotLight.intensity = 2;

// 设置阴影贴图模糊度
spotLight.shadow.radius = 20;
// 设置阴影贴图的分辨率
spotLight.shadow.mapSize.set(512, 512);

spotLight.target = cube;
spotLight.angle = Math.PI / 6;
spotLight.distance = 0;
spotLight.penumbra = 0;
spotLight.decay = 0;

// 设置透视相机的属性

scene.add(spotLight);
gui.add(cube.position, "x").min(-5).max(5).step(0.1);
gui.add(spotLight.position, "x").min(-20).max(20).step(0.1);
gui.add(spotLight.position, "y").min(-20).max(20).step(0.1);
gui.add(spotLight.position, "z").min(-20).max(20).step(0.1);
gui
  .add(spotLight, "angle")
  .min(0)
  .max(Math.PI / 2)
  .step(0.01);
gui.add(spotLight, "distance").min(0).max(100).step(0.1);
gui.add(spotLight, "penumbra").min(0).max(1).step(0.01);
gui.add(spotLight, "decay").min(0).max(5).step(0.01);

function render() {
  controls.update();
  renderer.render(scene, camera);
  //   渲染下一帧的时候就会调用render函数
  requestAnimationFrame(render);
}

render();

// 监听画面变化，更新渲染画面
window.addEventListener("resize", () => {
  //   console.log("画面变化了");
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  //   更新摄像机的投影矩阵
  camera.updateProjectionMatrix();

  //   更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  //   设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});
